package classification.slvm;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import classification.elemListRepr.XMLElement;
import classification.elemListRepr.XMLElementList;

import preprocess.Arith;

public class StructSimilarity extends ElementSimilarityMatrix
{
    private ElementSimilarityMatrix structureSimilarityMatrix = null;

    /* IO */
    private static PrintWriter      stdOut                    = new PrintWriter(
                                                                      System.out,
                                                                      true);

    public StructSimilarity()
    {

    }

    public StructSimilarity(int initXMLDocNum)
    {
        this.structureSimilarityMatrix = new ElementSimilarityMatrix();
    }

    /**
     * 通过遗传算法中的DNA得到该SLVMSimilarityMatrix对象的结构相似度矩阵
     * 
     * @param GA_DNA
     *            DNA
     * @param XMLElemNum
     *            XML 元素的个数
     */
    public void calcStructureSimiMatrix(int[] GA_DNA, int XMLElemNum)
    {
        int index = 0;
        for (int i = 0; i < XMLElemNum; i++)
        {
            for (int j = i; j < XMLElemNum; j++)
            {
                if (GA_DNA[index] != 0)
                {
                    this.structureSimilarityMatrix.addSimilarity(i, j,
                            GA_DNA[index]);
                }
                index++;
            }
        }

        for (int i = 0; i < XMLElemNum; i++)
        {
            for (int j = 0; j < i; j++)
            {
                double similarity = this.structureSimilarityMatrix
                        .getSimilarity(j, i);
                this.structureSimilarityMatrix.addSimilarity(i, j, similarity);
            }
        }
    }

    /**
     * 得到该SLVMSimilarityMatrix对象的文本相似度矩阵
     * 
     * @return 该SLVMSimilarityMatrix对象的文本相似度矩阵
     */
    public ElementSimilarityMatrix getStructSimiMatrix()
    {
        return this.structureSimilarityMatrix;
    }

    /**
     * 设置该SLVMSimilarityMatrix对象的文本相似度矩阵
     */
    public void setStructureSimiMatrix(
            final ElementSimilarityMatrix newStructSimiMatrix)
    {
        this.structureSimilarityMatrix = newStructSimiMatrix;
    }

    /**
     * 返回该DNA所对应的结构相似度矩阵
     * 
     * @param GA_DNA
     *            DNA
     * @param XMLElemNum
     *            XML 元素的个数
     * @return 该DNA所对应的结构相似度矩阵
     */
    public static ElementSimilarityMatrix DNAToStructSimiMatrix(int[] GA_DNA,
            int XMLElemNum)
    {
        ElementSimilarityMatrix Stru_Simi_Matrix = new ElementSimilarityMatrix();

        int index = 0;
        for (int i = 0; i < XMLElemNum; i++)
        {
            for (int j = i; j < XMLElemNum; j++)
            {
                Stru_Simi_Matrix.addSimilarity(i, j, GA_DNA[index++]);
            }
        }

        for (int i = 0; i < XMLElemNum; i++)
        {
            for (int j = 0; j < i; j++)
            {
                double similarity = Stru_Simi_Matrix.getSimilarity(j, i);
                Stru_Simi_Matrix.addSimilarity(i, j, similarity);
            }
        }

        return Stru_Simi_Matrix;
    }

    public static void DisplayStructSimiMatrix(
            ElementSimilarityMatrix structSimiMatrix,
            XMLElementList templateElemList)
    {
        int elemNum = templateElemList.getElemNum();
        String rowElemName = "";

        stdOut.print("\t");
        for (int i = 0; i < elemNum; i++)
        {
            stdOut.print(templateElemList.get(i).getXMLElemName() + "\t");
        }
        stdOut.println();

        for (int i = 0; i < elemNum; i++)
        {
            rowElemName = templateElemList.get(i).getXMLElemName();
            stdOut.print(rowElemName + "\t");
            for (int j = 0; j < elemNum; j++)
            {
                double similarity = structSimiMatrix.getSimilarity(i, j);
                stdOut.print(similarity + "\t");
            }
            stdOut.println();
        }
    }
}
